<?php
/** token基类 */
namespace app\api\service;

use app\lib\enum\ScopeEnum;
use app\lib\exception\ForbiddenException;
use app\lib\exception\TokenException;

use Exception;
use think\Cache;

class Token{
    //生成Token
    public static function generateToken(){
        //32个字符组成一组随机（无意义）字符串
        $randChars=getRandChar(32);
        //用三组字符串，进行md5加密
        $timestamp=$_SERVER['REQUEST_TIME_FLOAT'];
        //salt 盐（加密信息，随机信息）
        $salt=config('secure.token_salt');
        return md5($randChars.$timestamp.$salt);
    }

    //通用方法 参数指明获取哪个变量
    public static function getCurrentTokenVar($key){
        $token=Request()::instance()->header('token');
        $vars=Cache::get($token);//token即为键值
        if(!$vars){
            throw new TokenException();
        }else{
            if(!is_array($vars)){
                $vars=json_decode($vars,true);//字符串变数
            }
            if(array_key_exists($key,$vars)){//存在才返回
                return $vars[$key];
            }else{
                throw new Exception('尝试获取的Token变量并不存在');
            }
        }
    }

    //获取当前用户的Uid
    public static function getCurrentUid(){
        //把token作为健获取值(……) 把uid当成key
        $uid=self::getCurrentTokenVar('uid');
        return $uid;
    }  

    //需要用户和CMS管理员都可以访问的权限
    public static function needPrimaryScope(){
        $scope=self::getCurrentTokenVar('scope');
        if($scope){
            if($scope>=ScopeEnum::User){
                return true;
            }else{
                throw new ForbiddenException();
            }
        }else{
            throw new TokenException();
        }
    }

    //只有用户才能访问的权限
    public static function needExclusiveScope(){
        $scope=self::getCurrentTokenVar('scope');
        if($scope){
            if($scope==ScopeEnum::User){
                return true;
            }else{
                throw new ForbiddenException();
            }
        }else{
            throw new TokenException();
        }
    }

    //是否是一个合法操作
    public static function isValidOperate($checkedUID){
        if(!$checkedUID){//判空
            throw new Exception('检查UID时必须传入一个被检查的UID');
        }
        $currentOperateUID=self::getCurrentUid();
        if ($currentOperateUID==$checkedUID) {
            return true;
        }
        return false;
    }

    //校验token
    public static function verifyToken($token){
        //优化
        // if(!$token){
        //     throw new TokenException([
        //         'msg' => 'Token已过期或Token为空'
        //     ]);
        // }

        //判断token是否还存在缓存里
        $exist=Cache::get($token);
        if($exist){
            return true;
        }else{
            return false;
        }
    }

}